#pragma once

#include <string>
#include <map>
#include <mutex>
#include "qbprotocol/include/SSFilters.h"
#include "BondInfo.h"
#include "bondlib.h"
#include <core/strings/BaseString.h>
#include <core/sync/lock.h>

/*
[内存优化][scofined.qi]
REPORT加入到容器的时候,压缩编码成ReportEncoder::FieldArray对象
此对象内存后面紧接着实际的内容编码,FieldArray只是对象头部

普通访问模式下,FieldArray需要先转化成REPORT对象
快速模式下,如GetModifyTime,可以通过字段索引来直接访问REPORT的
某个成员,而不需要先转化成REPORT对象

优化措施:
	1.使用KeyString取代std::string
	2.使用vector取代原先的std::map
	3.使用编码后的FieldArray取代REPORT(压缩率是29%)
*/
using namespace std;
enum class kReportField{// 表示结构体report_t中每个字段的对应的序号,必须严格一一对应
	Version = 0,
	Market,
	BondKey,
	ListedMarket,
	Time,
	CreateTime,
	DealStatus,
	CompanyId,
	PriceStatus,

	// 对应price_t的字段顺序
	Bid_id,
	Bid_deal_status,
	Bid_flag_bargain,
	Bid_flag_relation,
	Bid_flag_vip,
	Bid_company_id,
	Bid_flag_bad,
	Bid_price_status,
	Bid_rebate,
	Bid_return_point,
	Bid_clean_price,
	Bid_yield_price,
	Bid_sPrice,
	Bid_quotetype,
	Bid_sVolume,
	Bid_description,
	Bid_interpret,
	Bid_create_time,
	Bid_time,

	// 对应price_t的字段顺序
	Ask_id,
	Ask_deal_status,
	Ask_flag_bargain,
	Ask_flag_relation,
	Ask_flag_vip,
	Ask_company_id,
	Ask_flag_bad,
	Ask_price_status,
	Ask_rebate,
	Ask_return_point,
	Ask_clean_price,
	Ask_yield_price,
	Ask_sPrice,
	Ask_quotetype,
	Ask_sVolume,
	Ask_description,
	Ask_interpret,
	Ask_create_time,
	Ask_time,

	// 对应indx_price_t的字段顺序
	Idx_symbol,
	Idx_price,
	Idx_clean_price,
	Idx_company_id,
	Idx_modify_time,

	PriceSel,
	TradePrice,
	PkgId,
	Count
};


class S_BONDLIB_EXPORT CCompanyRepMap
{
public:
	typedef std::map<std::string, REPORT> ReportMap;
	ReportMap m_map;	//<brokerID,REPORT>
};
template<typename CONTAINER>
class MapWrapper{
	typedef std::map<std::string, REPORT> ReportMap;
	typedef  typename CONTAINER::key_type key_type;
	//typedef  typename  CONTAINER::value_type value_type;
	typedef  typename  CONTAINER::mapped_type mapped_type;
	typedef  typename CONTAINER::iterator iterator;
	typedef  typename CONTAINER::const_iterator const_iterator;
	CONTAINER&	m_container;
public:
	MapWrapper(CONTAINER& cont) :m_container(cont){}
	iterator begin(){ return m_container.begin(); }
	iterator end(){ return m_container.end(); }
	iterator find(const key_type& key){ return m_container.find(key); }
	int size()const{ return m_container.size(); }
	int bytes()const{
		return 0;
	}
	void clear(){ m_container.clear(); }
	void emplace(const key_type& key, const mapped_type& rpt){
		m_container.emplace(key, rpt);
	}
	iterator erase(const_iterator _Where){ return m_container.erase(_Where); }
};


typedef qb::base::KeyString KeyString;
class ZippedReportMap;
class S_BONDLIB_EXPORT CBondCompanyRep
{
	typedef CCompanyRepMap::ReportMap ReportMap;
	typedef MapWrapper<ReportMap>   ReportMapWrapper;
public:
	class S_BONDLIB_EXPORT ApplyCallback{
	public:
		virtual bool DoAccess(const REPORT& quote){ return false; }//true表示可继续,false表示中断
		virtual bool DoModify(REPORT& quote){ return false; }//true表示可继续,false表示中断
	};
	CBondCompanyRep();
	virtual ~CBondCompanyRep();
	bool	Clear( );
	bool    ClearLiquidation(int clrFlag);

	int		GetSize();
	int		GetBytes(int mode=0);
	int		GetItemSize()const{ return sizeof(XCQUOTE); }
	const char* GetName()const;

	bool	InsertCompanyRep(const REPORT& newElement );
	bool	GetCompanyRepByKey(const std::string& sKey,REPORT &stRep);

	void	ApplyAccess(bool all, const std::string& sKey, ApplyCallback* callback);
	void	ApplyModify(bool all, const std::string& sKey, ApplyCallback* callback);

	//-------------------------------------------------------------------------
	// Summary:
	// 		根据key值得到报价信息，若sKey为空（全部时），则取所有Broker报价中的最新的报价
	// Parameters:
	// 		sKey - BrokerID
	// 		stRep - 报价
	// Returns:
	// 		若成功返回true,否则返回false
	//-------------------------------------------------------------------------
	bool    GetReport(const std::string& sKey,REPORT &stRep, int nFlag); //flag = 0 取最新，1 取最新有效，2 取最新双边

	// 由CBondContainer::GetLatestCompanyRepByBondIndex改造而来
	bool	GetLatestReport(REPORT &stRep, bool bBuyPool);

	bool TestBidPrice(const BLHCONDITION& Cond);
	bool TestOfrPrice(const BLHCONDITION& Cond);

	static bool	IsBidPriceValid(const REPORT &stRep);
	static bool	IsOfrPriceValid(const REPORT &stRep);
public://高性能接口
	time_t GetModifyTime(const std::string& szKey);
	double GetBuyNetPrice(const std::string& szKey);
	double GetBuyPrice(const std::string& key);
	double GetSellPrice(const std::string& key);
	double GetSellNetPrice(const std::string& key);
	const void* GetReportField(const char* key, int index);
	bool IsHasPrice(const char* szKey, uint32_t	nBnkFlg);
protected:
	ZippedReportMap*		m_zip;
	//CCompanyRepMap			m_RepMap;
	qb::base::Spinlock		m_lock;//TODO spin?
};
